/*
 * Copyright 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.noday.cat.service.impl;

import java.util.HashMap;
import java.util.Map;

import net.noday.cat.model.User;
import net.noday.cat.service.UserService;
import net.noday.core.pagination.Page;
import net.noday.core.security.Loginable;
import net.noday.core.security.SecurityDao;
import net.noday.core.security.ShiroDbRealm.ShiroUser;
import net.noday.core.service.SecurityService;
import net.noday.core.utils.Digests;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * cat SecurityService
 * 
 * @author <a href="http://www.noday.net">Noday</a>
 * @version , 2012-10-21
 * @since
 */
@Service
public class UserServiceImpl implements SecurityService<Loginable<Long>>,
		UserService {

	@Autowired
	private SecurityDao dao;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * net.noday.core.service.SecurityService#findPage(net.noday.core.model.
	 * User, net.noday.core.pagination.Page)
	 */
	@Override
	public void findPage(User condition, Page<User> pageData) {
		pageData.setPageCount(dao.findCount(condition));
		pageData.setRows(dao.findPage(condition, pageData.getPageIndex(),
				pageData.getSize()));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * net.noday.core.service.SecurityService#regist(net.noday.core.model.User)
	 */
	public Map<String, String> regist(User u) {
		Map<String, String> result = new HashMap<String, String>();
		// 0.email地址是否已经存在
		if (StringUtils.isBlank(u.getEmail()))
			result.put("email", "用户名为空");
		else {
			// 1.两次密码是否一致
			if (!u.getPassword().equals(u.getPlainPassword()))
				result.put("password", "两次密码不一致");
			else {
				// 2.用户是否已经存在
				User dbU = dao.findUserByLoginName(u.getEmail());
				if (dbU != null)
					result.put("email", "用户名不可用");
				else {
					entryptPassword(u);
					if (StringUtils.isBlank(u.getRole()))
						u.setRole("user");
					dao.save(u);
					result.put("1", "注册成功");
				}
			}
		}
		return result;
	}

	@Override
	public Map<String, String> update(User u) {
		Map<String, String> result = new HashMap<String, String>();
		// 1.两次密码是否一致
		if (!u.getPassword().equals(u.getPlainPassword()))
			result.put("password", "两次密码不一致");
		else {
			entryptPassword(u);
			if (dao.update(u))
				result.put("1", "修改成功");
			else
				result.put("1", "修改失败，请稍后再试");
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * net.noday.core.service.SecurityService#findUserByLoginName(java.lang.
	 * String)
	 */
	@Override
	public Loginable<Long> findUserByLoginName(String email) {
		User u = dao.findUserByLoginName(email);
		return u;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * net.noday.core.service.SecurityService#getUserByToken(java.lang.String)
	 */
	@Override
	public Loginable<Long> getUserByToken(String token) {
		Loginable<Long> u = new User();
		return u;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * net.noday.core.service.SecurityService#checkLogin(net.noday.core.model
	 * .User)
	 */
	@Override
	public boolean checkLogin(User u) {

		return true;
	}

	/**
	 * 判断是否超级管理员.
	 */
	public boolean isSupervisor(Long id) {
		return id == 1;
	}

	/**
	 * 取出Shiro中的当前用户LoginName.
	 */
	public String getCurrentUserName() {
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		return user.loginName;
	}

	/**
	 * 设定安全的密码，生成随机的salt并经过1024次 sha-1 hash
	 */
	private void entryptPassword(User user) {
		ByteSource salt = Digests.generateSalt(Digests.SALT_SIZE);
		user.setSalt(salt.toBase64());

		String hashPassword = Digests.sha256Hash(user.getPlainPassword(), salt,
				1024);
		user.setPassword(hashPassword);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see net.noday.core.service.SecurityService#checkLogin(java.lang.Object)
	 */
	@Override
	public boolean checkLogin(Loginable<Long> u) {
		// TODO Auto-generated method stub
		return false;
	}

}
